﻿// ———————————————————————–
// <copyright file="FeedService.svc.cs" company="The MITRE Corporation">
//    Copyright (c) 2010 The MITRE Corporation. All rights reserved.
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
// </copyright>
// ———————————————————————–
/////////////////////////////////////////////////////////////////////////////////////////////////
// FeedService.svc.cs - "Obtains Information From The ICNET Database And Formats It Into Feeds."
// Project: "IC.NETSOA"- "ICNETRest"
//
// Language:    C#, .NET 4.0
// Platform:    Windows 7, VS 2010
// Author:      Don McGarry The MITRE Corporation
/////////////////////////////////////////////////////////////////////////////////////////////////

// Copyright (c) 2010 The MITRE Corporation. All rights reserved.
//
// NOTICE
// This software was produced for the U. S. Government
// under Contract No. FA8721-09-C-0001, and is
// subject to the Rights in Noncommercial Computer Software
// and Noncommercial Computer Software Documentation Clause
// (DFARS) 252.227-7014 (JUN 1995)
                
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using EDXLSharp;
using ICNET_KMLStyleEngine;
using ICNETDAL;
using ICNETServices;
using Microsoft.ServiceModel.Web;


namespace ICNETREST
{
  /// <summary>
  /// Methods for pulling various types of informtion from the ICNET database and formatting it into feeds.
  /// </summary>
  [ServiceBehavior(IncludeExceptionDetailInFaults = true), AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed), ServiceContract(Namespace = "urn:icnet:mitre:org:FeedService")]
  public partial class FeedService
  {
    #region Public Methods
    /// <summary>
    /// Gets all GeoRSS feeds.
    /// </summary>
    /// <returns>Atom feed in response to a HTTP GET request at URLs conforming to the URI template of the WebGetAttribute.</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.AllGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetAllGeoRSSFeed()
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items;
      items = GeoRSSDal.GetAllGeoRSS();
      feed.Title = new TextSyndicationContent("IC.NET All Items Feed: ");
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }

    /// <summary>
    /// Gets all GeoRSS feeds.
    /// </summary>
    /// <returns>Atom feed in response to a HTTP GET request at URLs conforming to the URI template of the WebGetAttribute.</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.ActiveGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetActiveGeoRSSFeed()
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items;
      items = GeoRSSDal.GetActiveGeoRSS();
      feed.Title = new TextSyndicationContent("IC.NET Active Items Feed: ");
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }

    /// <summary>
    /// Gets all GeoRSS feeds.
    /// </summary>
    /// <returns>Atom feed in response to a HTTP GET request at URLs conforming to the URI template of the WebGetAttribute.</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.ExpiredGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetExpiredGeoRSSFeed()
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items;
      items = GeoRSSDal.GetExpiredGeoRSS();
      feed.Title = new TextSyndicationContent("IC.NET Expired Items Feed: ");
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }



    /// <summary>
    /// Gets GeoRSS feeds for a cetain role and converts them to Atom.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A GeoRSS feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.UpdatedRoleParamGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetUpdateRoleParamGeoRSSFeed(string since, string role, string roleURI)
    {
      DateTime sinceDT;
      if (DateTime.TryParse(since, out sinceDT))
      {
        SyndicationFeed feed = new SyndicationFeed();
        XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
        String icnetNs = ICNETSOAConstants.ICNETNamespace;
        feed.AttributeExtensions.Add(n, icnetNs);

        List<SyndicationItem> items = new List<SyndicationItem>();
        if (string.IsNullOrWhiteSpace(role))
        {
          items = GeoRSSDal.GetUpdatedGeoRSS(sinceDT);
          feed.Title = new TextSyndicationContent("IC.NET Update Feed Since: " + sinceDT.ToString("dddd, MMMM dd, yyyy, hh:mm:ss tt"));
        }
        else
        {
          items = GeoRSSDal.GetUpdatedSyndicationItemsByRole(sinceDT, role, roleURI);
          feed.Title = new TextSyndicationContent("IC.NET Update Feed For Role: " + role + ", Since: " + sinceDT.ToString("dddd, MMMM dd, yyyy, hh:mm:ss tt"));
        }
        
        feed.Items = items;
        feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
        feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
        WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
        return feed.GetAtom10Formatter();
      }
      else
      {
        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
        return null;
      }
    }

    /// <summary>
    /// Gets GeoRSS feeds for a cetain role.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A GeoRSS feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.UpdatedRoleGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetUpdatedRoleGeoRSSFeed(string role, string since, string roleURI)
    {
      DateTime sinceDT;
      if (DateTime.TryParse(since, out sinceDT))
      {
        SyndicationFeed feed = new SyndicationFeed();
        XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
        String icnetNs = ICNETSOAConstants.ICNETNamespace;
        feed.AttributeExtensions.Add(n, icnetNs);

        List<SyndicationItem> items = new List<SyndicationItem>();
        items = GeoRSSDal.GetUpdatedSyndicationItemsByRole(sinceDT, role, roleURI);
        feed.Title = new TextSyndicationContent("IC.NET Updated Feed For Role: " + role + ", Since: " + sinceDT.ToString("dddd, MMMM dd, yyyy, hh:mm:ss tt"));
        feed.Items = items;
        feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
        feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
        WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
        return feed.GetAtom10Formatter();
      }
      else
      {
        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
        return null;
      }
    }




    /// <summary>
    /// Gets active KML feed for a cetain role.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A KML feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.ActiveRoleKMLUri)]
    [OperationContract]
    public XElement GetActiveRoleKMLFeed(string role, string roleURI)
    {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        KMLDal.GetActiveKMLByRole(xmlWriter, role, roleURI);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
    }



    /// <summary>
    /// Gets active KML link feed for a cetain role.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A KML Link for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.ActiveRoleKMLLinkUri)]
    [OperationContract]
    public XElement GetActiveRoleKMLLinkFeed(string role, string roleURI)
    {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        xmlWriter.WriteStartElement("NetworkLink"); // start NetworkLink element
        xmlWriter.WriteAttributeString("id", "ID");
        xmlWriter.WriteElementString("name", "Network Feed");
        xmlWriter.WriteElementString("open", "1");
        xmlWriter.WriteStartElement("Link");  // start Link element
        xmlWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/Feeds/Active/" + role + @"/KML?RoleURI=" + roleURI);
        xmlWriter.WriteElementString("refreshMode", "onInterval");
        xmlWriter.WriteElementString("refreshInterval", ICNETSOAConstants.KMLLinkRefreshInSeconds.ToString()); //Used by Google Earth
        xmlWriter.WriteElementString("viewRefreshMode", "never");
        xmlWriter.WriteElementString("viewRefreshTime", "1");
        xmlWriter.WriteEndElement();  // end Link element
        xmlWriter.WriteEndElement();  // end NetworkLink element
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();

        // KMZDal.GetAllKMZ();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
    }



    ///// <summary>
    ///// Gets all GeoRSS feeds.
    ///// </summary>
    ///// <returns>Atom feed in response to a HTTP GET request at URLs conforming to the URI template of the WebGetAttribute.</returns>
    //[WebHelp(Comment = "Sample description for GetFeed.")]
    //[WebGet(UriTemplate = UriTemplates.UpdatedRSSUri)]
    //[OperationContract]
    //public Atom10FeedFormatter GetUpdatedGeoRSSFeed(string since)
    //{
    //  DateTime sinceDT;
    //  if (DateTime.TryParse(since, out sinceDT))
    //  {
    //    SyndicationFeed feed = new SyndicationFeed();
    //    List<SyndicationItem> items;
    //    items = GeoRSSDal.GetUpdatedGeoRSS(sinceDT);
    //    feed.Title = new TextSyndicationContent("IC.NET All Items Test Feed: ");
    //    feed.Items = items;
    //    feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
    //    feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
    //    WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
    //    return feed.GetAtom10Formatter();
    //  }
    //  else
    //  {
    //    WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
    //    return null;
    //  }
    //}

    /// <summary>
    /// Returns a List of Active feeds.
    /// </summary>
    /// <returns>Atom feed in response to a HTTP GET request at URLs conforming to the URI template of the WebGetAttribute.</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.AvailableFeedUri)]
    [OperationContract]
    public XElement GetAvailableFeeds(string format)
    {
      return GetAvailableFeedsAsXML(format);
    }

    /// <summary>
    /// Returns a List of Active feeds as XML.
    /// </summary>
    /// <returns>Atom feed in response to a HTTP GET request at URLs conforming to the URI template of the WebGetAttribute.</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.AvailableFeedAsXMLUri)]
    [OperationContract]
    public XElement GetAvailableFeedsAsXML(string format)
    {
      StringBuilder sb = new StringBuilder();
      XmlWriter xmlWriter = XmlWriter.Create(sb);
      xmlWriter.WriteStartDocument(false);
      xmlWriter.WriteStartElement("Feeds");
      VLList rules = RouterRulesDAL.GetAvailableFeedsFromRules();
      foreach (ValueList rule in rules)
      {
        foreach (string value in rule.Value)
        {
          xmlWriter.WriteStartElement("feed");
          xmlWriter.WriteElementString("name", value);
          xmlWriter.WriteElementString("description", "A feed for "+value);
          xmlWriter.WriteElementString("uri", ICNETSOAConstants.ICNETbaseURI + "/Feeds/" + value + "/"+format+"?RoleURI=" + rule.ValueListURN);
          xmlWriter.WriteEndElement();
        }
      }

      xmlWriter.WriteEndElement();
      xmlWriter.WriteEndDocument();
      xmlWriter.Flush();
      xmlWriter.Close();
      return XElement.Parse(sb.ToString());
    }

    /// <summary>
    /// Returns a List of Active feeds as an RSS feed
    /// </summary>
    /// <returns>An RSS feed</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.AvailableFeedAsRSSUri)]
    [OperationContract]
    public Rss20FeedFormatter GetAvailableFeedsAsRSS(string format)
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items = new List<SyndicationItem>();

      // populate items list
      
      VLList rules = RouterRulesDAL.GetAvailableFeedsFromRules();
      int id = 0;
      SyndicationItem myItem;
      foreach (ValueList rule in rules)
      {
        foreach (string value in rule.Value)
        {
          
          myItem = new SyndicationItem();
          myItem.Authors.Add(new SyndicationPerson("IC.NET"));
          myItem.BaseUri = new Uri(ICNETSOAConstants.ICNETbaseURI);
          myItem.Content = new TextSyndicationContent("");
          myItem.Copyright = new TextSyndicationContent("");
          

          myItem.Id = ""+id;
          id++;
          myItem.LastUpdatedTime = DateTimeOffset.Now;


          myItem.Links.Add(new SyndicationLink(new Uri(ICNETSOAConstants.ICNETbaseURI + "/Feeds/" + value + "/" + format + "?RoleURI=" + rule.ValueListURN), "alternate", "Feed link", "text/xml", 0));
          myItem.Links.Add(new SyndicationLink(new Uri(ICNETSOAConstants.ICNETbaseURI + "/Feeds/Active/" + value + "/" + format + "?RoleURI=" + rule.ValueListURN), "alternate", "Feed link", "text/xml", 0));
          myItem.Links.Add(new SyndicationLink(new Uri(ICNETSOAConstants.ICNETbaseURI + "/Feeds/Expired/" + value + "/" + format + "?RoleURI=" + rule.ValueListURN), "alternate", "Feed link", "text/xml", 0));
          myItem.Links.Add(new SyndicationLink(new Uri(ICNETSOAConstants.ICNETbaseURI + "/Feeds/Updated/" + value + "/" + format + "?Since='some time'&RoleURI=" + rule.ValueListURN), "alternate", "Feed link", "text/xml", 0));
          myItem.PublishDate = DateTimeOffset.Now;
          String roleString = rule.ValueListURN.Substring(rule.ValueListURN.LastIndexOf("/")+1);
          myItem.Summary = new TextSyndicationContent("IC.NET " + value + " feed for the " + roleString + " role");
          myItem.Title = new TextSyndicationContent(value);
          items.Add(myItem);
          
        }
      }


      feed.Title = new TextSyndicationContent("IC.NET Available Feeds on "+ICNETSOAConstants.ICNETbaseURI+": ");
      feed.Items = items;
      feed.LastUpdatedTime = DateTimeOffset.Now;


      return new Rss20FeedFormatter(feed, false);
    }

    /// <summary>
    /// Gets GeoRSS feeds for a cetain role.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A GeoRSS feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.RoleGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetRoleGeoRSSFeed(string role, string roleURI)
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items = new List<SyndicationItem>();
      items = GeoRSSDal.GetSyndicationItemsByRole(role, roleURI);
      feed.Title = new TextSyndicationContent("IC.NET Custom Feed For Role: " + role);
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }

    /// <summary>
    /// Gets GeoRSS feeds for a cetain role.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A GeoRSS feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.ActiveRoleGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetActiveRoleGeoRSSFeed(string role, string roleURI)
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items = new List<SyndicationItem>();
      items = GeoRSSDal.GetActiveSyndicationItemsByRole(role, roleURI);
      feed.Title = new TextSyndicationContent("IC.NET Active Feed For Role: " + role);
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }

    /// <summary>
    /// Gets GeoRSS feeds for a cetain role.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A GeoRSS feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.ExpiredRoleGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetExpiredRoleGeoRSSFeed(string role, string roleURI)
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items = new List<SyndicationItem>();
      items = GeoRSSDal.GetExpiredSyndicationItemsByRole(role, roleURI);
      feed.Title = new TextSyndicationContent("IC.NET Expired Feed For Role: " + role);
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }



    /// <summary>
    /// Gets GeoRSS feeds for a cetain role and converts them to Atom.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A GeoRSS feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.RoleParamGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetRoleParamGeoRSSFeed(string role, string roleURI)
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items = new List<SyndicationItem>();
      items = GeoRSSDal.GetSyndicationItemsByRole(role, roleURI);
      feed.Title = new TextSyndicationContent("IC.NET Custom Feed For Role: " + role);
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }

    /// <summary>
    /// Gets GeoRSS feeds for a cetain role and converts them to Atom.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A GeoRSS feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.ActiveRoleParamGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetActiveRoleParamGeoRSSFeed(string role, string roleURI)
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items = new List<SyndicationItem>();
      items = GeoRSSDal.GetActiveSyndicationItemsByRole(role, roleURI);
      feed.Title = new TextSyndicationContent("IC.NET Active Feed For Role: " + role);
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }

    /// <summary>
    /// Gets GeoRSS feeds for a cetain role and converts them to Atom.
    /// </summary>
    /// <param name="role">The role that the feed is based off of.</param>
    /// <param name="roleURI">The URI for the ValueList that contains the role</param>
    /// <returns>A GeoRSS feed for the given role</returns>
    [WebHelp(Comment = "Sample description for GetFeed.")]
    [WebGet(UriTemplate = UriTemplates.ExpiredRoleParamGeoRSSUri)]
    [OperationContract]
    public Atom10FeedFormatter GetExpiredRoleParamGeoRSSFeed(string role, string roleURI)
    {
      SyndicationFeed feed = new SyndicationFeed();
      XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
      String icnetNs = ICNETSOAConstants.ICNETNamespace;
      feed.AttributeExtensions.Add(n, icnetNs);

      List<SyndicationItem> items = new List<SyndicationItem>();
      items = GeoRSSDal.GetExpiredSyndicationItemsByRole(role, roleURI);
      feed.Title = new TextSyndicationContent("IC.NET Expired Feed For Role: " + role);
      feed.Items = items;
      feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
      feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
      WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
      return feed.GetAtom10Formatter();
    }

    /// <summary>
    /// Gets all of the objects in the database as XML
    /// </summary>
    /// <param name="format">Can be "XML" or "KML". </param>
    /// <returns>The formated XML if format = "XML". If format = "KML", it will be formatted as KML</returns>
    [WebGet(UriTemplate = UriTemplates.AllFormatUri)]
    [OperationContract]
    public XElement GetAllXMLFeed(string format)
    {
      if (format.Equals("KML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        KMLDal.GetAllKML(xmlWriter);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();

        // KMZDal.GetAllKMZ();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("XML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawXMLDAL.GetAllXML();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("DEXML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawDEXMLDAL.GetAllDEXML();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("DELink", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawDEXMLDAL.GetAllDELink();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("KMLLink", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        xmlWriter.WriteStartElement("NetworkLink"); // start NetworkLink element
        xmlWriter.WriteAttributeString("id", "ID");
        xmlWriter.WriteElementString("name", "Network Feed");
        xmlWriter.WriteElementString("open", "1");
        xmlWriter.WriteStartElement("Link");  // start Link element
        // XWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/FeedService.svc/all/KML"); //request for dev server testing
        xmlWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/Feeds/All/KML");
        xmlWriter.WriteElementString("refreshMode", "onInterval");
        xmlWriter.WriteElementString("refreshInterval", ICNETSOAConstants.KMLLinkRefreshInSeconds.ToString()); //Used by Google Earth
        xmlWriter.WriteElementString("viewRefreshMode", "never");
        xmlWriter.WriteElementString("viewRefreshTime", "1");
        xmlWriter.WriteEndElement();  // end Link element
        xmlWriter.WriteEndElement();  // end NetworkLink element
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();

        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
      }
      else
      {
        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
        return null;
      }
    }

    /// <summary>
    /// Gets the XML objects in the database that correspond to a certain role. 
    /// </summary>
    /// <param name="role">The role around which the feed will be based.</param>
    /// <param name="format">Can be "XML" or "KML". </param>
    /// <param name="roleURI">The URI of the ValueList that contains the role.</param>
    /// <returns>The formated XML if format = "XML". If format = "KML", it will be formatted as KML.</returns>
    [WebGet(UriTemplate = UriTemplates.RoleFormatUri)]
    [OperationContract]
    public XElement GetFormatXMLFeed(string role, string format, string roleURI)
    {
      if (format.Equals("KML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        KMLDal.GetKMLByRole(xmlWriter, role, roleURI);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("KMLLink", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        xmlWriter.WriteStartElement("NetworkLink"); // start NetworkLink element
        xmlWriter.WriteAttributeString("id", "ID");
        xmlWriter.WriteElementString("name", "Network Feed");
        xmlWriter.WriteElementString("open", "1");
        xmlWriter.WriteStartElement("Link");  // start Link element
        // XWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/FeedService.svc/" + role + @"/KML?RoleURI=" + roleURI);  // request for dev server testing
        xmlWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/Feeds/" + role + @"/KML?RoleURI=" + roleURI);
        xmlWriter.WriteElementString("refreshMode", "onInterval");
        xmlWriter.WriteElementString("refreshInterval", ICNETSOAConstants.KMLLinkRefreshInSeconds.ToString()); //Used by Google Earth
        xmlWriter.WriteElementString("viewRefreshMode", "never");
        xmlWriter.WriteElementString("viewRefreshTime", "1");
        xmlWriter.WriteEndElement();  // end Link element
        xmlWriter.WriteEndElement();  // end NetworkLink element
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();

        // KMZDal.GetAllKMZ();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("XML", StringComparison.CurrentCultureIgnoreCase))
      {
        return null;
      }
      else if (format.Equals("DEXML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawDEXMLDAL.GetDEByRole(role, roleURI);
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("DELink", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawDEXMLDAL.GetDELinkByRole(role, roleURI);
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else
      {
        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
        return null;
      }
    }

    /// <summary>
    /// Gets all of the objects in the database as XML
    /// </summary>
    /// <param name="format">Can be "XML" or "KML". </param>
    /// <returns>The formated XML if format = "XML". If format = "KML", it will be formatted as KML</returns>
    [WebGet(UriTemplate = UriTemplates.ActiveFormatUri)]
    [OperationContract]
    public XElement GetActiveXMLFeed(string format)
    {
      if (format.Equals("KML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        KMLDal.GetActiveKML(xmlWriter);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();

        // KMZDal.GetAllKMZ();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("XML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawXMLDAL.GetActiveXML();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("DEXML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawDEXMLDAL.GetActiveDEXML();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("DELink", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawDEXMLDAL.GetActiveDELink();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("KMLLink", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        xmlWriter.WriteStartElement("NetworkLink"); // start NetworkLink element
        xmlWriter.WriteAttributeString("id", "ID");
        xmlWriter.WriteElementString("name", "Network Feed");
        xmlWriter.WriteElementString("open", "1");
        xmlWriter.WriteStartElement("Link");  // start Link element
        // XWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/FeedService.svc/all/KML"); //request for dev server testing
        xmlWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/Feeds/Active/KML");
        xmlWriter.WriteElementString("refreshMode", "onInterval");
        xmlWriter.WriteElementString("refreshInterval", ICNETSOAConstants.KMLLinkRefreshInSeconds.ToString()); //Used by Google Earth
        xmlWriter.WriteElementString("viewRefreshMode", "never");
        xmlWriter.WriteElementString("viewRefreshTime", "1");
        xmlWriter.WriteEndElement();  // end Link element
        xmlWriter.WriteEndElement();  // end NetworkLink element
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();

        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
      }
      else
      {
        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
        return null;
      }
    }

    /// <summary>
    /// Gets all of the objects in the database as XML
    /// </summary>
    /// <param name="format">Can be "XML" or "KML". </param>
    /// <returns>The formated XML if format = "XML". If format = "KML", it will be formatted as KML</returns>
    [WebGet(UriTemplate = UriTemplates.ExpiredFormatUri)]
    [OperationContract]
    public XElement GetExpiredXMLFeed(string format)
    {
      if (format.Equals("KML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        KMLDal.GetExpiredKML(xmlWriter);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();

        // KMZDal.GetAllKMZ();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("XML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawXMLDAL.GetExpiredXML();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("DEXML", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawDEXMLDAL.GetExpiredDEXML();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("DELink", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("items");
        List<XElement> items = RawDEXMLDAL.GetExpiredDELink();
        foreach (XElement item in items)
        {
          item.WriteTo(xmlWriter);
        }

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
        return XElement.Parse(sb.ToString());
      }
      else if (format.Equals("KMLLink", StringComparison.CurrentCultureIgnoreCase))
      {
        StringBuilder sb = new StringBuilder();
        XmlWriter xmlWriter = XmlWriter.Create(sb);
        xmlWriter.WriteStartDocument(false);
        xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
        xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
        xmlWriter.WriteStartElement("Document");
        xmlWriter.WriteElementString("name", "IC.NET KML Feed");
        xmlWriter.WriteStartElement("NetworkLink"); // start NetworkLink element
        xmlWriter.WriteAttributeString("id", "ID");
        xmlWriter.WriteElementString("name", "Network Feed");
        xmlWriter.WriteElementString("open", "1");
        xmlWriter.WriteStartElement("Link");  // start Link element
        // XWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/FeedService.svc/all/KML"); //request for dev server testing
        xmlWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/Feeds/Expired/KML");
        xmlWriter.WriteElementString("refreshMode", "onInterval");
        xmlWriter.WriteElementString("refreshInterval", ICNETSOAConstants.KMLLinkRefreshInSeconds.ToString()); //Used by Google Earth
        xmlWriter.WriteElementString("viewRefreshMode", "never");
        xmlWriter.WriteElementString("viewRefreshTime", "1");
        xmlWriter.WriteEndElement();  // end Link element
        xmlWriter.WriteEndElement();  // end NetworkLink element
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();

        WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
        return XElement.Parse(sb.ToString());
      }
      else
      {
        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
        return null;
      }
    }

    /// <summary>
    /// Gets all of the objects in the database as XML
    /// </summary>
    /// <param name="format">Can be "XML" or "KML". </param>
    /// <returns>The formated XML if format = "XML". If format = "KML", it will be formatted as KML</returns>
    [WebGet(UriTemplate = UriTemplates.UpdatedFormatUri)]
    [OperationContract]
    public XElement GetUpdatedXMLFeed(string format, string since)
    {
      DateTime sinceDT;
      if (DateTime.TryParse(since, out sinceDT))
      {
        if (format.Equals("KML", StringComparison.CurrentCultureIgnoreCase))
        {
       
          StringBuilder sb = new StringBuilder();
          XmlWriter xmlWriter = XmlWriter.Create(sb);
          xmlWriter.WriteStartDocument(false);
          xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
          xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
          xmlWriter.WriteStartElement("Document");
          xmlWriter.WriteElementString("name", "IC.NET KML Feed");
          KMLDal.GetUpdatedKML(sinceDT, xmlWriter);
          xmlWriter.WriteEndElement();
          xmlWriter.WriteEndDocument();
          xmlWriter.Flush();
          xmlWriter.Close();

          WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
          return XElement.Parse(sb.ToString());
        }
        else if (format.Equals("GeoRSS", StringComparison.CurrentCultureIgnoreCase))
        {
            if (DateTime.TryParse(since, out sinceDT))
            {
                SyndicationFeed feed = new SyndicationFeed();
                XmlQualifiedName n = new XmlQualifiedName(ICNETSOAConstants.ICNETQualifiedName, "http://www.w3.org/2000/xmlns/");
                String icnetNs = ICNETSOAConstants.ICNETNamespace;
                feed.AttributeExtensions.Add(n, icnetNs);

                List<SyndicationItem> items = new List<SyndicationItem>();
                items = GeoRSSDal.GetUpdatedGeoRSS(sinceDT);
                feed.Title = new TextSyndicationContent("IC.NET Update Feed Since: " + sinceDT.ToString("dddd, MMMM dd, yyyy, hh:mm:ss tt"));
                feed.Items = items;
                feed.LastUpdatedTime = this.GetMostRecentSyndicationItemTime(items);
                feed.AddSelfLink(WebOperationContext.Current.IncomingRequest.GetRequestUri());
                WebOperationContext.Current.OutgoingResponse.ContentType = ContentTypes.Atom;
                XElement feedAsXML = new XElement("dummy");
                
                feed.GetAtom10Formatter().WriteTo(feedAsXML.CreateWriter());
                return feedAsXML.Element("feed");
            }
            else
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
                return null;
            }
        }
        else if (format.Equals("XML", StringComparison.CurrentCultureIgnoreCase))
        {
            StringBuilder sb = new StringBuilder();
            XmlWriter xmlWriter = XmlWriter.Create(sb);
            xmlWriter.WriteStartDocument(false);
            xmlWriter.WriteStartElement("items");
            List<XElement> items = RawXMLDAL.GetUpdatedXML(sinceDT);
            foreach (XElement item in items)
            {
                item.WriteTo(xmlWriter);
            }

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Flush();
            xmlWriter.Close();
            WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
            return XElement.Parse(sb.ToString());
        }
        else if (format.Equals("DEXML", StringComparison.CurrentCultureIgnoreCase))
        {
            StringBuilder sb = new StringBuilder();
            XmlWriter xmlWriter = XmlWriter.Create(sb);
            xmlWriter.WriteStartDocument(false);
            xmlWriter.WriteStartElement("items");
            List<XElement> items = RawDEXMLDAL.GetUpdatedDEXML(sinceDT);
            foreach (XElement item in items)
            {
                item.WriteTo(xmlWriter);
            }

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Flush();
            xmlWriter.Close();
            WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
            return XElement.Parse(sb.ToString());
        }
        else if (format.Equals("DELink", StringComparison.CurrentCultureIgnoreCase))
        {
            StringBuilder sb = new StringBuilder();
            XmlWriter xmlWriter = XmlWriter.Create(sb);
            xmlWriter.WriteStartDocument(false);
            xmlWriter.WriteStartElement("items");
            List<XElement> items = RawDEXMLDAL.GetUpdatedDELink(sinceDT);
            foreach (XElement item in items)
            {
                item.WriteTo(xmlWriter);
            }

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Flush();
            xmlWriter.Close();
            WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
            return XElement.Parse(sb.ToString());
        }
        else if (format.Equals("KMLLink", StringComparison.CurrentCultureIgnoreCase))
        {
            StringBuilder sb = new StringBuilder();
            XmlWriter xmlWriter = XmlWriter.Create(sb);
            xmlWriter.WriteStartDocument(false);
            xmlWriter.WriteStartElement("kml", "http://earth.google.com/kml/2.0");
            xmlWriter.WriteAttributeString("xmlns", "atom", null, "http://www.w3.org/2005/Atom");
            xmlWriter.WriteStartElement("Document");
            xmlWriter.WriteElementString("name", "IC.NET KML Feed");
            xmlWriter.WriteStartElement("NetworkLink"); // start NetworkLink element
            xmlWriter.WriteAttributeString("id", "ID");
            xmlWriter.WriteElementString("name", "Network Feed");
            xmlWriter.WriteElementString("open", "1");
            xmlWriter.WriteStartElement("Link");  // start Link element
            // XWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/FeedService.svc/all/KML"); //request for dev server testing
            xmlWriter.WriteElementString("href", ICNETSOAConstants.ICNETbaseURI + @"/Feeds/Updated/KML?since=" + since);
            xmlWriter.WriteElementString("refreshMode", "onInterval");
            xmlWriter.WriteElementString("refreshInterval", ICNETSOAConstants.KMLLinkRefreshInSeconds.ToString()); //Used by Google Earth
            xmlWriter.WriteElementString("viewRefreshMode", "never");
            xmlWriter.WriteElementString("viewRefreshTime", "1");
            xmlWriter.WriteEndElement();  // end Link element
            xmlWriter.WriteEndElement();  // end NetworkLink element
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Flush();
            xmlWriter.Close();

            WebOperationContext.Current.OutgoingResponse.ContentType = "application/vnd.google-earth.kml+xml";
            return XElement.Parse(sb.ToString());
        }
        else
        {
            WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
            return null;
        }
      }
      else
      {
        WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
        return null;
      }
    }
    #endregion

    /// <summary>
   /// Iterates thorugh a list of syndication items to find the date of the most recent one. 
   /// </summary>
   /// <param name="items">The list to be iterated through. </param>
   /// <returns>The date and time of the most recent item.</returns>
    private DateTimeOffset GetMostRecentSyndicationItemTime(List<SyndicationItem> items)
    {
      if (items.Count == 0)
      {
        return DateTimeOffset.Now;
      }

      DateTimeOffset mostRecentTime = items[0].LastUpdatedTime;
      foreach (SyndicationItem item in items)
      {
        if (item.LastUpdatedTime.CompareTo(mostRecentTime) < 0)
        {
          mostRecentTime = item.LastUpdatedTime;
        }
      }

      return mostRecentTime;
    }
  }
}
